package com.eva.ss;

import com.eva.framework.config.AppConfig;
import com.eva.framework.rbac.model.RbacUserInfo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * Spring Security配置
 * EnableGlobalMethodSecurity注解说明
 * - prePostEnabled：是否启用@PreAuthorize权限控制注解
 * - securedEnabled：是否启用@Secured权限控制注解
 */
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {

    @Resource
    private AppConfig appConfig;

    @Resource
    private UserDetailsServiceImpl userDetailsService;

    @Resource
    private DefaultAuthenticationEntryPoint defaultAuthenticationEntryPoint;

    @Lazy
    @Resource
    private DefaultPreAuthFilter defaultPreAuthFilter;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        AppConfig.SessionConfig.Interceptor sessionInterceptorConfig = appConfig.getSession().getInterceptor();
        // 匿名访问配置
        httpSecurity.exceptionHandling()
                .authenticationEntryPoint(defaultAuthenticationEntryPoint)
        ;

        // 拦截配置
        httpSecurity.authorizeRequests()
                // 先指定放行路径
                .antMatchers(sessionInterceptorConfig.getExcludePathPatterns()).permitAll()
                // 后指定拦截路径
                .antMatchers(sessionInterceptorConfig.getPathPatterns()).authenticated()
        ;

        // 不创建Session
        httpSecurity
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        ;

        // 禁用csrf防护
        httpSecurity.csrf().disable();

        // 添加预认证过滤器
        httpSecurity.addFilterBefore(defaultPreAuthFilter, UsernamePasswordAuthenticationFilter.class);
        return httpSecurity.build();
    }

    /**
     * 声明AuthenticationManager实例，采用自定义身份认证
     */
    @Bean
    public AuthenticationManager authenticationManager() {
        DefaultDaoAuthenticationProvider provider = new DefaultDaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        return new ProviderManager(provider);
    }
}
